// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.


/****************************************************************************
						Microsoft RPC 
       
                        umarsh Example

    FILE:       umarshcu.c

    PURPOSE:    Utility functions used by client side of the RPC
                distributed application.
                This sample demonstrates the represent_as attribute.      

    RELATED:    umarshs.c - server main
                umarshp.c - remote procedures
                umarshc.c - client main

    FUNCTIONS:  WCHAR_STRING_to_local    - convert WCHAR_STRING to CHAR_STRING
                WCHAR_STRING_from_local  - convert WCHAR_STRING from CHAR_STRING
                WCHAR_STRING_free_inst   - free WCHAR_STRING memory
                WCHAR_STRING_free_local  - free CHAR_STRING memory
                midl_user_allocate - user-supplied memory allocator
                midl_user_free - user-supplied routine to free memory


    COMMENTS:   This sample program generates a client and server can share
                an interface, but one side can use a different representation
                than the other.

                The client side in this example does all operations using
                character strings, and the server side does all operations
                using UNICODE strings.  Two procedures are provided, one
                defined with ASCII strings, one with UNICODE strings.
                The wire format reflects these definitions, yet the client
                and server see pure ASCII and pure UNICODE respectively.

                The [represent_as] attribute (used in the client and server
                side acf files) requires the four user-supplied functions
                whose names start with the name of the transmitted type
                (in the client side's case: WCHAR_STRING)

                The [in, out] attributes applied to remote procedure
                parameters require the two user-supplied functions
                midl_user_allocate and midl_user_free.

                The other functions are utilities that are used to
                build or display the data structures.

****************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include "umarshc.h"    // header file generated by MIDL compiler for client


// Calculate size that converted data will 
// require in the buffer
unsigned long __RPC_USER CHAR_STRING_UserSize( 
    ULONG __RPC_FAR * pulFlags, 
    unsigned long    startingSize,
	 CHAR_STRING __RPC_FAR * pWire){
		 return startingSize + sizeof(WCHAR_STRING);
}

unsigned char * __RPC_USER CHAR_STRING_UserMarshal( 
    ULONG __RPC_FAR *pulFlags, 
    unsigned char __RPC_FAR * pBufferStart, 
	CHAR_STRING __RPC_FAR * pStr){	

	unsigned char __RPC_FAR * pCurBuffer = pBufferStart;

	size_t uSize;

	mbstowcs_s(&uSize,(wchar_t *)pBufferStart,sizeof(WCHAR_STRING), *pStr, sizeof(WCHAR_STRING) );

	((wchar_t *)pCurBuffer) += STRING_SIZE;

	return pCurBuffer;

	
}

unsigned char * __RPC_USER CHAR_STRING_UserUnmarshal( 
    ULONG __RPC_FAR * pulFlags, 
    unsigned char __RPC_FAR * pBufferStart, 
	CHAR_STRING __RPC_FAR * pStr){	

	size_t uSize;
	
	unsigned char __RPC_FAR * pCurBuffer = pBufferStart;

	wcstombs_s(&uSize,*pStr, sizeof(CHAR_STRING), (wchar_t *)pBufferStart, sizeof(CHAR_STRING) );

    ((wchar_t *)pCurBuffer) += STRING_SIZE;

	return pCurBuffer;
}

void __RPC_USER CHAR_STRING_UserFree( 
    ULONG __RPC_FAR * pulFlags, 
    CHAR_STRING __RPC_FAR * pStr){
		//free(pStr);
}

// Calculate size that converted data will 
// require in the buffer
unsigned long __RPC_USER CHAR_STRING_UserSize64( 
    ULONG __RPC_FAR * pulFlags, 
    unsigned long    startingSize,
	 CHAR_STRING __RPC_FAR * pWire){
		 return startingSize + sizeof(WCHAR_STRING);
}

unsigned char * __RPC_USER CHAR_STRING_UserMarshal64( 
    ULONG __RPC_FAR *pulFlags, 
    unsigned char __RPC_FAR * pBufferStart, 
	CHAR_STRING __RPC_FAR * pStr){	

	unsigned char __RPC_FAR * pCurBuffer = pBufferStart;

	size_t uSize;

	mbstowcs_s(&uSize,(wchar_t *)pBufferStart,sizeof(WCHAR_STRING), *pStr, sizeof(WCHAR_STRING) );

	((wchar_t *)pCurBuffer) += STRING_SIZE;

	return pCurBuffer;	
}

unsigned char * __RPC_USER CHAR_STRING_UserUnmarshal64( 
    ULONG __RPC_FAR * pulFlags, 
    unsigned char __RPC_FAR * pBufferStart, 
	CHAR_STRING __RPC_FAR * pStr){	

	size_t uSize;
	
	unsigned char __RPC_FAR * pCurBuffer = pBufferStart;

	wcstombs_s(&uSize,*pStr, sizeof(CHAR_STRING), (wchar_t *)pBufferStart, sizeof(CHAR_STRING) );

       ((wchar_t *)pCurBuffer) += STRING_SIZE;

	return pCurBuffer;
}

void __RPC_USER CHAR_STRING_UserFree64( 
    ULONG __RPC_FAR * pulFlags, 
    CHAR_STRING __RPC_FAR * pStr){
		//free(pStr);
}

/***************************************************************************/

void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
    return(malloc(len));
}

void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
    free(ptr);
}


/***************************************************************************/

/* end file umarshcu.c */
